/* Copyright  2009
   @Author
   Richard Changde Yin            e-mail yinchangde@hotmail.com

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 of the License.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
   
/**
 *@filename:  from_unixtime.cc
 */ 


#include <server_includes.h>
#include CSTDINT_H
#include <function/time/from_unixtime.h>
#include <session.h>

#include "temporal.h"

#include <sstream>
#include <string>

void Item_func_from_unixtime::fix_length_and_dec()
{
  session= current_session;
  collation.set(&my_charset_bin);
  decimals= DATETIME_DEC;
  max_length=MAX_DATETIME_WIDTH*COLLAPSAR_CHARSET_BIN_MB_MAXLEN;
  maybe_null= 1;
}

String *Item_func_from_unixtime::val_str(String *str)
{
  COLLAPSAR_TIME time_tmp;

  assert(fixed == 1);

  if (get_date(&time_tmp, 0))
    return 0;

  if (str->alloc(MAX_DATE_STRING_REP_LENGTH))
  {
    null_value= 1;
    return 0;
  }

  make_datetime(&time_tmp, str);

  return str;
}

int64_t Item_func_from_unixtime::val_int()
{
  COLLAPSAR_TIME time_tmp;

  assert(fixed == 1);

  if (get_date(&time_tmp, 0))
    return 0;

  return (int64_t) TIME_to_uint64_t_datetime(&time_tmp);
}

bool Item_func_from_unixtime::get_date(COLLAPSAR_TIME *ltime, uint32_t)
{
  uint64_t tmp= (uint64_t)(args[0]->val_int());
  /*
    "tmp > TIMESTAMP_MAX_VALUE" check also covers case of negative
    from_unixtime() argument since tmp is unsigned.
  */
  if ((null_value= (args[0]->null_value || tmp > TIMESTAMP_MAX_VALUE)))
    return 1;

  collapsar::Timestamp temporal;
  if (! temporal.from_time_t((time_t) tmp))
  {
    null_value= true;
    std::stringstream ss;
    std::string tmp_string;
    ss << tmp; ss >> tmp_string;
    my_error(ER_INVALID_UNIX_TIMESTAMP_VALUE, MYF(0), tmp_string.c_str());
    return 0;
  }
  
  memset(ltime, 0, sizeof(*ltime));

  ltime->year   = temporal.years();
  ltime->month  = temporal.months();
  ltime->day    = temporal.days();
  ltime->hour   = temporal.hours();
  ltime->minute = temporal.minutes();
  ltime->second = temporal.seconds();
  ltime->time_type= COLLAPSAR_TIMESTAMP_DATETIME;

  return 0;
}
